﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Login;
using FEM.Result;
using PGMHelper;
using SectionAnalysis;
using Newtonsoft.Json;

namespace PBSD_Development
{
   
    /// <summary>
    /// 截面基类
    /// </summary>
    public class Section
    {
        /// <summary>
        /// 截面
        /// </summary>
        protected FEM.Basic.CrossSection secion { set; get; }

        /// <summary>
        /// 抗剪承载力
        /// </summary>
        protected CapacityObj ShearCapacity { set; get; }

        /// <summary>
        /// 抗弯承载力
        /// </summary>
        protected CapacityObj MomentCapacity { set; get; }

        /// <summary>
        /// 剪跨长度
        /// </summary>
        protected double shearSpan { set; get; }

        /// <summary>
        /// 轴力
        /// </summary>
        protected double axialLoad { set; get; }

        /// <summary>
        /// 破坏形态
        /// </summary>
        protected DamageMode damageMode { set; get; }

        /// <summary>
        /// 变形限值
        /// </summary>
        protected List<double> limits { set; get; }

        /// <summary>
        /// 弯剪比
        /// </summary>
        protected double msr { set; get; }

        /// <summary>
        /// 弯剪比
        /// </summary>
        public double MSR
        {
            get
            {
                return this.msr;
            }
        }

        /// <summary>
        /// 剪跨比
        /// </summary>
        public double Lammda
        {
            get
            {
                //截面信息是否有误
                if (!this.isSectionCorrect()) return 0;
                return (this.shearSpan / (this.GetSectionHeight() - this.secion.Cover));
            }
        }

        /// <summary>
        /// 轴压比
        /// </summary>
        public virtual double AxialLoadRatio
        {
            get
            {
                return 0;
            }
        }

        /// <summary>
        /// 截面信息是否完整
        /// </summary>
        /// <returns></returns>
        protected virtual bool isSectionCorrect()
        {
            return false;
        }

        /// <summary>
        /// 获得等效高度
        /// </summary>
        /// <returns></returns>
        protected virtual double GetSectionHeight()
        {
            return 0;
        }

        /// <summary>
        /// 设定变形限值
        /// </summary>
        /// <param name="isPosLoading"> 是否正向加载（剪力墙i端受拉） </param>
        /// <param name="shearForce"> 剪力大小（部分截面类型用于计算剪压比） </param>
        /// <returns> 是否成功 </returns>
        public virtual bool SetLimits(bool isPosLoading, double shearForce = 0)
        {
            return false;
        }

        /// <summary>
        /// 计算抗剪承载力
        /// </summary>
        /// <param name="capacity"> 抗剪承载力 </param>
        /// <returns> 成功 </returns>
        public virtual bool GetShearCapacityObj(out CapacityObj capacity)
        {
            capacity = this.ShearCapacity;
            return false;
        }

        /// <summary>
        /// 设定抗弯承载力
        /// </summary>
        /// <param name="zipJson"></param>
        protected bool setMomentCapacity(string zipJson, int theta, 
            out SectionAnalysisResult saSection)
        {
            //初始化
            saSection = new SectionAnalysisResult();
            //判断登录情况
            if (!LoginState.Check()) return false;
            //请求云端分析结果
            var RESULT = string.Empty;
            //请求云端函数
            if (!LoadingForm.GetHttpResponse("SingleSectionPM", 
                zipJson, "截面分析", false, ref RESULT))
                return false;
            //获得截面
            saSection = JsonConvert.DeserializeObject<SectionAnalysisResult>(ZipHelper.DecompressString(RESULT));
            //计算抗弯承载力
            var design = saSection.DesignResult.GetMoment(theta, this.axialLoad);
            var basic = saSection.BasciResult.GetMoment(theta, this.axialLoad);
            var avg = saSection.AVGResult.GetMoment(theta, this.axialLoad);
            //设定承载力
            this.MomentCapacity = new CapacityObj(design, basic, avg);
            return true;
        }

        /// <summary>
        /// 设定SRC构件材料强度
        /// </summary>
        /// <param name="concreteGrade"> 混凝土等级 </param>
        /// <param name="barGrade"> 纵筋强度 </param>
        /// <param name="stirrupGrade"> 箍筋强度 </param>
        /// <param name="steelGrade"> 型钢强度 </param>
        public void SetSRCMaterial(int concreteGrade, int barGrade, int stirrupGrade, int steelGrade)
        {
            this.secion.Concrete_Grade = concreteGrade;
            this.secion.Bar_Grade = barGrade;
            this.secion.Stirrup_Grade = stirrupGrade;
            this.secion.Steel_Grade = steelGrade;
        }

        /// <summary>
        /// 设定RC构件材料强度
        /// </summary>
        /// <param name="concreteGrade"> 混凝土立方体抗压强度 </param>
        /// <param name="barGrade"> 纵筋强度 </param>
        /// <param name="stirrupGrade"> 箍筋强度 </param>
        public void SetRCMaterial(int concreteGrade, int barGrade, int stirrupGrade)
        {
            this.SetSRCMaterial(concreteGrade, barGrade, stirrupGrade, 0);
        }

        /// <summary>
        /// 设定RC构件材料强度
        /// </summary>
        /// <param name="concreteGrade"> 混凝土抗压强度标准值 </param>
        /// <param name="barGrade"> 纵筋强度 </param>
        /// <param name="stirrupGrade"> 箍筋强度 </param>
        public void SetRCMaterialWithFck(double concreteGrade, int barGrade, int stirrupGrade)
        {
            this.SetSRCMaterialWithFck(concreteGrade, barGrade, stirrupGrade, 0);
        }

        /// <summary>
        /// 设定SRC构件材料强度
        /// </summary>
        /// <param name="concreteGrade"> 混凝土抗压强度标准值 </param>
        /// <param name="barGrade"> 纵筋强度 </param>
        /// <param name="stirrupGrade"> 箍筋强度 </param>
        /// <param name="steelGrade"> 型钢强度 </param>
        public void SetSRCMaterialWithFck(double concreteGrade, int barGrade, int stirrupGrade, int steelGrade)
        {
            this.SetSRCMaterial((int)this.GetFcu(concreteGrade), barGrade, stirrupGrade, steelGrade);
        }


        /// <summary>
        /// 抗弯承载力
        /// </summary>
        /// <param name="capacityType"> 承载力类型：设计值、标准值、平均值 </param>
        /// <returns> 承载力 </returns>
        public double GetMomentCapacity(CapacityType capacityType)
        {
            return this.MomentCapacity[capacityType];
        }

        /// <summary>
        /// 抗弯承载力
        /// </summary>
        /// <param name="forceType"> 剪力/弯矩 </param>
        /// <param name="capacityType"> 承载力类型：设计值、标准值、平均值 </param>
        /// <returns> 承载力 </returns>
        public double GetShearCapacity(CapacityType capacityType)
        {
            return this.ShearCapacity[capacityType];
        }

        /// <summary>
        /// 计算立方体抗压强度
        /// </summary>
        /// <param name="fck"></param>
        /// <returns></returns>
        private double GetFcu(double fck)
        {
            //(混规条文说明4.1.3)
            //系数
            double afa_1 = 0.0;
            double afa_2 = 0.0;
            //混凝土强度小于C40（标准强度）
            if (fck <= 26.81)
            {
                afa_1 = 0.76;
                afa_2 = 1;
            }
            //混凝土强度小于C50（标准强度）
            else if (fck <= 32.41)
            {
                afa_1 = 0.76;
                afa_2 = 1 - (0.13) / (50.2 - 26.81) * (fck - 26.81);
            }
            //混凝土强度小于C80（标准强度）
            else if (fck <= 50.21)
            {
                afa_1 = 0.76 + (0.06) / (50.2 - 32.4) * (fck - 32.4);
                afa_2 = 1 - (0.13) / (50.2 - 29.6) * (fck - 29.6);
            }
            else
            {
                afa_1 = 0.82;
                afa_2 = 0.87;
            }
            //立方体抗压强度（混规条文说明4.1.3）
            var fcu = fck / (0.88 * afa_1 * afa_2);
            //以5为模
            fcu = (int)(fcu / 5) * 5;
            return fcu < 5 ? 5 : fcu;
        }

        /// <summary>
        /// 变形限值
        /// </summary>
        /// <returns> 变形限值 </returns>
        public List<double> GetLimits()
        {
            return (from limit in this.limits select limit).ToList();
        }

        /// <summary>
        /// 破坏形态
        /// </summary>
        /// <returns> 破坏形态 </returns>
        public DamageMode GetDamageMode()
        {
            return this.damageMode;
        }

        /// <summary>
        /// 性能状态
        /// </summary>
        /// <param name="rotation"> 构件变形 </param>
        /// <returns> 性能状态 </returns>
        public DeformType GetPerform(double rotation)
        {
            //变形限值有误
            if (this.limits.Count == 0)
            {
                MessageBoxExtern.Error("未计算性能指标限值");
                return DeformType.Integrity;
            }
            //遍历限值
            for (int i = 0; i < this.limits.Count; i++)
            {
                if (this.limits[i] >= Math.Abs(rotation))
                    return (DeformType)i;
            }
            //构件失效
            return DeformType.Collapse;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        protected Section()
        {
            this.shearSpan = 0;
            this.axialLoad = 0;
            this.ShearCapacity = new CapacityObj();
            this.MomentCapacity = new CapacityObj();
            this.limits = new List<double>();
        }
    }
}
